package main

import (
	"net/http"
	"html/template"
	"time"
	"os/signal"
	"./common"
	"os"
	"./router"
	"context"
	"fmt"
	"flag"
	"./ctrl"
)

//注册模版
func RegisterView(mux *http.ServeMux) {
	//解析模版
	tpl, err := template.ParseGlob("view/**/*") //ParseGlob满足这种格式的都可以展示出来,**表示目录,*表示文件
	if err != nil {
		common.G_logger.Fatal(err.Error()) //打印模版渲染错误信息，log.fatal直接退出并打印
	}

	for _, v := range tpl.Templates() {
		//循环注册模版
		tplname := v.Name()
		mux.HandleFunc(tplname, func(w http.ResponseWriter, r *http.Request) {
			tpl.ExecuteTemplate(w, tplname, nil)
		})
	}
}

func main() {
	var (
		err    error
		wait   time.Duration
		server *http.Server
		c      chan os.Signal
	)

	//日志初始化
	common.InitLogger()

	//配置文件初始化
	if err = common.InitConfig(); err != nil {
		common.G_logger.Fatal(err.Error())
	}

	//数据库初始化
	if err = common.InitMysql(); err != nil {
		common.G_logger.Fatal(err.Error())
	}

	//创建存储图片资源的目录
	if err = os.MkdirAll("./mnt", os.ModePerm); err != nil {
		common.G_logger.Fatal(err.Error())
	}

	//初始化推送线程
	ctrl.InitPush()

	flag.DurationVar(&wait, "graceful-timeout", time.Second*15, "服务器优雅地等待现有连接完成的持续时间,例如15秒或1m")
	flag.Parse()

	fmt.Println("flagvar has value ", wait)

	//优雅的终止服务ctrl +c == kill -2 pid
	server = &http.Server{
		Addr:           ":" + common.G_config.HttpServerPort,
		WriteTimeout:   4 * time.Second,
		ReadTimeout:    10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}

	mux := http.NewServeMux()

	//注册路由
	router.Router(mux)

	//注册静态资源
	mux.Handle("/asset/", http.FileServer(http.Dir(".")))
	mux.Handle("/mnt/", http.FileServer(http.Dir(".")))
	//注册模版
	RegisterView(mux)

	server.Handler = mux

	go func() {
		if err := server.ListenAndServe(); err != nil {
			common.G_logger.Fatal(err)
		}
	}()

	c = make(chan os.Signal, 1)
	//当通过SIGINT (Ctrl+C)退出时，我们将接受优雅的关闭
	//不会捕获SIGKILL、SIGQUIT或SIGTERM (Ctrl+/)
	signal.Notify(c, os.Interrupt)

	//直到我们收到信号为止
	<-c

	//设定一个等待的截止时间
	ctx, cancel := context.WithTimeout(context.Background(), wait)
	defer cancel()
	//如果没有连接，则不会阻塞，否则将等到超时截止日期。
	server.Shutdown(ctx)
	//您可以选择运行srv。如果您的应用程序应该基于上下文取消等待其他服务完成，则在goroutine中关闭并阻塞<-ctx.Done()
	common.G_logger.Info("Server stop success...")

	os.Exit(0)
}
